Default, Named, and Parameterized Constructors in Dart
Constructors are an important part of Object-Oriented Programming (OOP) in Dart.
They are used when creating objects and are commonly used to initialize the data
stored inside those objects.
JustAcademy's Flutter curriculum includes Dart Programming Fundamentals and specifically
covers Object-Oriented Programming, classes, objects, and constructors. These concepts
provide an important foundation for Flutter application development.
:contentReference[oaicite:0]{index=0}
1. What is a Constructor?
A constructor is a special member of a class that is invoked when
an object is created. It is commonly used to initialize the object's properties.
For example:
class Student {
String name;
int age;
Student(this.name, this.age);
}
void main() {
Student student = Student("Rahul", 20);
print(student.name);
print(student.age);
}
Here, Student(this.name, this.age) is the constructor. It receives
values and initializes the object's properties.
2. Types of Constructors Covered in This Topic
The three important constructor patterns discussed in this topic are:
- Default Constructor
- Parameterized Constructor
- Named Constructor
Each type provides a different way of creating and initializing objects.
3. Default Constructor
A default constructor is the constructor used when an object is created without
supplying initialization arguments. In Dart, when a class has no explicitly
declared constructor, an implicit default constructor is available in the
appropriate cases.
Example
class Student {
String name = "Rahul";
int age = 20;
}
void main() {
Student student = Student();
print(student.name);
print(student.age);
}
Output:
Rahul
20
In this example, Student() creates an object without passing any
arguments.
4. Explicit Default Constructor
You can also explicitly define a constructor that takes no parameters.
class Car {
String brand = "Toyota";
Car() {
print("Car object created");
}
}
void main() {
Car car = Car();
print(car.brand);
}
Output:
Car object created
Toyota
5. When to Use a Default Constructor
A default constructor is useful when an object can be created with predefined or
default values.
class User {
String name = "Guest";
bool isLoggedIn = false;
User();
}
void main() {
User user = User();
print(user.name);
print(user.isLoggedIn);
}
6. Parameterized Constructor
A parameterized constructor accepts one or more values when an object is created.
It allows different objects of the same class to be initialized with different data.
Basic Example
class Student {
String name;
int age;
Student(this.name, this.age);
}
void main() {
Student student1 = Student("Rahul", 20);
Student student2 = Student("Priya", 22);
print(student1.name);
print(student2.name);
}
Both objects are created using the same constructor, but they contain different values.
7. Parameterized Constructor with Multiple Values
class Employee {
String name;
int age;
double salary;
Employee(this.name, this.age, this.salary);
}
void main() {
Employee employee = Employee(
"Amit",
25,
50000,
);
print(employee.name);
print(employee.age);
print(employee.salary);
}
The constructor receives three parameters:
8. Parameterized Constructor Using the this Keyword
Dart provides a convenient constructor syntax using this.
class Product {
String name;
double price;
Product(this.name, this.price);
}
The above constructor initializes the instance fields directly.
The same initialization can be written more explicitly as:
class Product {
String name;
double price;
Product(String name, double price) {
this.name = name;
this.price = price;
}
}
9. Creating Multiple Objects Using a Parameterized Constructor
class Product {
String name;
double price;
Product(this.name, this.price);
void display() {
print("Product: $name");
print("Price: ₹$price");
}
}
void main() {
Product product1 = Product("Laptop", 50000);
Product product2 = Product("Mobile", 25000);
Product product3 = Product("Headphones", 3000);
product1.display();
product2.display();
product3.display();
}
10. Named Constructor
A named constructor is a constructor with an additional name.
It allows a class to provide multiple meaningful ways of creating objects.
Example
class User {
String name;
int age;
User(this.name, this.age);
User.guest()
: name = "Guest",
age = 0;
}
void main() {
User user1 = User("Rahul", 25);
User user2 = User.guest();
print(user1.name);
print(user2.name);
}
Here:
User() is the main constructor.
User.guest() is a named constructor.
11. Why Use Named Constructors?
Named constructors are useful when a class needs multiple meaningful ways of
initializing an object.
For example, a User object might be created normally or as a guest.
class User {
String name;
String role;
User(this.name, this.role);
User.admin(String name)
: this(name, "Admin");
User.guest()
: name = "Guest",
role = "Guest";
}
void main() {
User normalUser = User("Rahul", "Student");
User adminUser = User.admin("Amit");
User guestUser = User.guest();
print(normalUser.role);
print(adminUser.role);
print(guestUser.role);
}
12. Multiple Named Constructors
A class can have more than one named constructor.
class Product {
String name;
double price;
Product(this.name, this.price);
Product.free(this.name)
: price = 0;
Product.discounted(this.name, double originalPrice)
: price = originalPrice * 0.8;
}
void main() {
Product normal = Product("Laptop", 50000);
Product freeProduct = Product.free("Sample");
Product discounted = Product.discounted("Mobile", 30000);
print(normal.price);
print(freeProduct.price);
print(discounted.price);
}
13. Named Constructor with a Different Initialization Method
Named constructors can be useful for expressing different creation scenarios.
class Employee {
String name;
double salary;
Employee(this.name, this.salary);
Employee.manager(String name)
: this(name, 80000);
Employee.intern(String name)
: this(name, 20000);
}
void main() {
Employee employee1 =
Employee.manager("Amit");
Employee employee2 =
Employee.intern("Rahul");
print(employee1.salary);
print(employee2.salary);
}
14. Default vs Parameterized vs Named Constructors
Feature |
Default Constructor |
Parameterized Constructor |
Named Constructor |
|---|
Arguments |
Usually none |
Accepts values |
Can accept values |
Purpose |
Create an object with default initialization |
Initialize an object with supplied data |
Provide a named creation pattern |
Example |
Student() |
Student("Rahul", 20) |
User.guest() |
Multiple forms |
Limited to one unnamed constructor |
Can use different signatures through named constructors |
Multiple named constructors can exist |
15. Default Constructor Example
class Mobile {
String brand = "Samsung";
double price = 20000;
Mobile();
}
void main() {
Mobile mobile = Mobile();
print(mobile.brand);
print(mobile.price);
}
16. Parameterized Constructor Example
class Mobile {
String brand;
double price;
Mobile(this.brand, this.price);
}
void main() {
Mobile mobile = Mobile(
"Samsung",
20000,
);
print(mobile.brand);
print(mobile.price);
}
17. Named Constructor Example
class Mobile {
String brand;
double price;
Mobile(this.brand, this.price);
Mobile.budget(String brand)
: this(brand, 10000);
}
void main() {
Mobile mobile = Mobile.budget("Samsung");
print(mobile.brand);
print(mobile.price);
}
18. Named Parameters in Constructors
Named constructors and named parameters are different concepts. A constructor can
use named parameters even when it is the unnamed constructor.
class Student {
String name;
int age;
String course;
Student({
required this.name,
required this.age,
required this.course,
});
}
void main() {
Student student = Student(
name: "Rahul",
age: 20,
course: "Flutter",
);
print(student.name);
print(student.course);
}
Here, Student() is the unnamed constructor, while
name, age, and course are named parameters.
19. Important Difference: Named Constructor vs Named Parameter
Named Constructor |
Named Parameter |
|---|
Provides another constructor name. |
Provides a name for an argument. |
Example: User.guest() |
Example: User(name: "Rahul") |
Defines another object-creation path. |
Makes constructor arguments clearer. |
20. Required Named Parameters
The required keyword can make named constructor parameters mandatory.
class Product {
String name;
double price;
Product({
required this.name,
required this.price,
});
}
void main() {
Product product = Product(
name: "Laptop",
price: 50000,
);
print(product.name);
}
21. Optional Named Parameters
Named parameters can also have default values.
class User {
String name;
int age;
User({
this.name = "Guest",
this.age = 18,
});
}
void main() {
User user1 = User();
User user2 = User(
name: "Rahul",
age: 25,
);
print(user1.name);
print(user1.age);
print(user2.name);
print(user2.age);
}
22. Parameterized Constructor with Optional Positional Parameters
Dart also supports optional positional parameters using square brackets.
class User {
String name;
int age;
User(this.name, [this.age = 18]);
}
void main() {
User user1 = User("Rahul");
User user2 = User("Priya", 25);
print(user1.age);
print(user2.age);
}
23. Constructor with Final Properties
Constructors are commonly used to initialize final fields because
final instance fields must be initialized before the object is ready for use.
class User {
final int id;
final String name;
User(this.id, this.name);
}
void main() {
User user = User(
101,
"Rahul",
);
print(user.id);
print(user.name);
}
24. Initializer List with a Constructor
An initializer list can be used to initialize fields before the constructor body executes.
class Rectangle {
final double width;
final double height;
final double area;
Rectangle(this.width, this.height)
: area = width * height;
void display() {
print("Area: $area");
}
}
void main() {
Rectangle rectangle = Rectangle(10, 5);
rectangle.display();
}
25. Redirecting Constructor
A named constructor can redirect to another constructor in the same class. This
allows common initialization logic to be reused.
class Student {
String name;
int age;
Student(this.name, this.age);
Student.fromName(String name)
: this(name, 18);
}
void main() {
Student student = Student.fromName("Rahul");
print(student.name);
print(student.age);
}
26. Practical Example: Student Management
class Student {
String name;
int age;
String course;
Student(this.name, this.age, this.course);
Student.guest()
: name = "Guest",
age = 0,
course = "Not Assigned";
void display() {
print("Name: $name");
print("Age: $age");
print("Course: $course");
}
}
void main() {
Student student1 =
Student("Rahul", 20, "Flutter");
Student student2 =
Student.guest();
student1.display();
print("");
student2.display();
}
27. Practical Example: E-Commerce Product
class Product {
String name;
double price;
int quantity;
Product(this.name, this.price, this.quantity);
Product.free(String name)
: this(name, 0, 1);
Product.single(String name, double price)
: this(name, price, 1);
double get totalPrice {
return price * quantity;
}
}
void main() {
Product product1 =
Product("Laptop", 50000, 2);
Product product2 =
Product.free("Sample");
Product product3 =
Product.single("Mobile", 25000);
print(product1.totalPrice);
print(product2.totalPrice);
print(product3.totalPrice);
}
28. Practical Example: Bank Account
class BankAccount {
String accountNumber;
String holderName;
double balance;
BankAccount(
this.accountNumber,
this.holderName,
this.balance,
);
BankAccount.empty(
this.accountNumber,
this.holderName,
) : balance = 0;
void display() {
print("Account: $accountNumber");
print("Holder: $holderName");
print("Balance: ₹$balance");
}
}
void main() {
BankAccount account1 = BankAccount(
"ACC101",
"Rahul",
10000,
);
BankAccount account2 = BankAccount.empty(
"ACC102",
"Priya",
);
account1.display();
print("");
account2.display();
}
29. Constructors in Flutter
Constructors are used extensively in Flutter widgets. A custom widget can receive
values through its constructor and use those values while building its UI.
import 'package:flutter/material.dart';
class WelcomeCard extends StatelessWidget {
final String title;
final String message;
const WelcomeCard({
super.key,
required this.title,
required this.message,
});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Text(title),
Text(message),
],
),
),
);
}
}
The widget can be created using:
WelcomeCard(
title: "Welcome",
message: "Learn Flutter with Dart",
)
30. Constructors and Flutter Model Classes
Constructors are also useful for creating model objects used to represent application data.
class User {
final int id;
final String name;
final String email;
User({
required this.id,
required this.name,
required this.email,
});
}
void main() {
User user = User(
id: 101,
name: "Rahul",
email: "[email protected]",
);
print(user.name);
}
31. Constructor from JSON Data
A factory constructor can be used to create a Dart object from JSON-style data.
class Product {
final int id;
final String name;
final double price;
Product({
required this.id,
required this.name,
required this.price,
});
factory Product.fromJson(Map<String, dynamic> json) {
return Product(
id: json["id"] as int,
name: json["name"] as String,
price: (json["price"] as num).toDouble(),
);
}
}
void main() {
Map<String, dynamic> data = {
"id": 101,
"name": "Laptop",
"price": 50000,
};
Product product = Product.fromJson(data);
print(product.name);
print(product.price);
}
32. Constructor Comparison Example
class User {
String name;
int age;
// Default / no-argument constructor
User()
: name = "Guest",
age = 0;
// Named constructor
User.guest()
: name = "Guest",
age = 0;
// Parameterized constructor
User.withDetails(this.name, this.age);
}
void main() {
User user1 = User();
User user2 = User.guest();
User user3 = User.withDetails("Rahul", 25);
print(user1.name);
print(user2.name);
print(user3.name);
}
33. Important Dart Constructor Rules
- A class can have multiple named constructors.
- A class cannot have two constructors with exactly the same name and parameter signature.
- The unnamed constructor is written using the class name itself.
- Named constructors use the class name followed by a dot and a constructor name.
- Constructors can use positional parameters.
- Constructors can use named parameters.
- Named parameters can be marked
required.
- Initializer lists can be used for field initialization.
- Constructors can redirect to other constructors.
- Const constructors can support compile-time constant objects.
- Factory constructors can control which object is returned.
34. Common Mistakes
Mistake 1: Confusing Named Constructors and Named Parameters
// Named constructor
User.guest();
// Named parameters
User(
name: "Rahul",
age: 20,
);
These are two different Dart features.
Mistake 2: Forgetting Required Parameters
class Product {
String name;
double price;
Product({
required this.name,
required this.price,
});
}
Both name and price must be supplied when creating the object.
Mistake 3: Reassigning a Final Field
class User {
final int id;
User(this.id);
}
The id field cannot be reassigned after initialization.
35. Best Practices
- Use a simple unnamed constructor for straightforward object creation.
- Use parameterized constructors when objects require different initial values.
- Use named constructors when a class has multiple meaningful creation patterns.
- Use named parameters for constructors with several arguments.
- Use
required for mandatory named parameters.
- Use
final for values that should not change after object initialization.
- Use initializer lists for calculated or validated initialization.
- Keep constructors readable and focused on initialization.
- Use descriptive names for named constructors such as
fromJson(),
guest(), or fromDatabase() when appropriate.
36. Practice Exercises
Create a Book class with a default constructor.
Create a Student class with a parameterized constructor.
Create a User class with a guest() named constructor.
Create an Employee class with two named constructors:
manager() and intern().
Create a Product class using required named parameters.
Create a class containing a final field initialized through its constructor.
Create a class with an initializer list.
Create a Product.fromJson() factory constructor.
Create a Flutter widget that accepts two values through its constructor.
37. Quick Revision Table
Constructor |
Purpose |
Example |
|---|
Default |
Creates an object without supplied constructor arguments. |
Student() |
Parameterized |
Initializes an object using supplied values. |
Student("Rahul", 20) |
Named |
Provides an additional named way to create an object. |
User.guest() |
Named Parameters |
Makes constructor arguments explicit by name. |
name: "Rahul" |
Required Named Parameters |
Makes selected named arguments mandatory. |
required this.name |
Redirecting Constructor |
Delegates initialization to another constructor. |
: this(...) |
38. Key Takeaways
- Constructors initialize objects when they are created.
- A default or no-argument constructor creates an object without supplied initialization arguments.
- A parameterized constructor accepts values during object creation.
- A named constructor provides an additional named creation path.
- Named constructors and named parameters are different concepts.
- Named parameters can be positional-independent and can be marked
required.
- Constructors can initialize
final properties.
- Initializer lists provide another way to initialize fields.
- Constructors are widely used in Flutter widgets and Dart model classes.
39. Learn Flutter with JustAcademy
JustAcademy's Flutter Training curriculum includes Dart programming fundamentals,
Object-Oriented Programming in Dart, and classes, objects, and constructors. The
broader curriculum continues into Flutter widgets, UI design, navigation, state
management, APIs, Firebase, testing, deployment, and project development.
:contentReference[oaicite:1]{index=1}
target="_blank"
rel="noopener noreferrer">
Visit JustAcademy Flutter Training
target="_blank"
rel="noopener noreferrer">
Register for JustAcademy Course Demo